package com.yict.csms.company.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yict.common.entity.PageEntity;
import com.yict.common.service.impl.CommonService;
import com.yict.csms.company.dao.impl.ContractRateDaoImpl;
import com.yict.csms.company.entity.ContractRate;
import com.yict.csms.company.service.IContractRateService;
import com.yict.csms.system.entity.BudgetNum;

/**
 * 
 * 
 * @author Patrick.Deng
 * 
 */
@Service
public class ContractRateServiceImpl extends CommonService<ContractRate, Long>
		implements IContractRateService {
	@Autowired
	private ContractRateDaoImpl contractRateDao;

	public List<ContractRate> search(Map<String, Object> queryMap, PageEntity page) {
		StringBuilder queryString = new StringBuilder();
		pageEntity = new PageEntity();
		queryString.append("from ContractRate as c where 1=1");
		if (queryMap != null && queryMap.size() > 0) {
			if (queryMap.get("companyIdList") != null && !"".equals(queryMap.get("companyIdList"))) {
				queryString.append(" and c.company.companyId in (:companyIdList)");
			}
			if (queryMap.get("companyName") != null && !"".equals(queryMap.get("companyName"))) {
				queryString.append(" and lower(c.company.companyName) like :companyName");
				queryMap.put("companyName", queryMap.get("companyName").toString().toLowerCase());
			}
			if (queryMap.get("contractNo") != null && !"".equals(queryMap.get("contractNo"))) {
				queryString.append(" and lower(c.contract.contractNo) like :contractNo");
				queryMap.put("contractNo", queryMap.get("contractNo").toString().toLowerCase());
			}
			if (queryMap.get("contractTypeIdList") != null && !"".equals(queryMap.get("contractTypeIdList"))) {
				queryString.append(" and c.contract.contractType.typeId in (:contractTypeIdList)");
			}
			if (queryMap.get("wharfTArray") != null && !"".equals(queryMap.get("wharfTArray"))) {
				String[] wharf = (String[]) queryMap.get("wharfTArray");
				queryString.append(" and (");
				int i = 1;
				for (String string : wharf) {
					queryString.append(" c.contract.wharf like " + "'%" + string + "%'");
					if(i != wharf.length) {
						queryString.append(" or");
					}
					i++;
				}
				queryString.append(" )");
				queryMap.remove("wharfTArray");
			}
			if (queryMap.get("effectiveDate1") != null && !"".equals(queryMap.get("effectiveDate1"))) {
				queryString.append(" and c.effectiveDate >= to_date(:effectiveDate1,'yyyy-MM-dd')" );
				if(queryMap.get("effectiveDate2") != null && !"".equals(queryMap.get("effectiveDate2"))) {
					queryString.append(" and c.effectiveDate <= to_date(:effectiveDate2,'yyyy-MM-dd')");
				}
			}
			if (queryMap.get("expirationDate1") != null && !"".equals(queryMap.get("expirationDate1"))) {
				queryString.append(" and c.expirationDate >= to_date(:expirationDate1,'yyyy-MM-dd') " );
				if(queryMap.get("expirationDate2") != null && !"".equals(queryMap.get("expirationDate2"))) {
					queryString.append(" and c.expirationDate <= to_date(:expirationDate2,'yyyy-MM-dd')");
				}
			}
			if (queryMap.get("accountMethodCode") != null && !"".equals(queryMap.get("accountMethodCode"))) {
				queryString.append(" and c.profession.accountmethod = :accountMethodCode");
			}
			if (queryMap.get("professionIdList") != null && !"".equals(queryMap.get("professionIdList"))) {
				queryString.append(" and c.profession.profeid in (:professionIdList)");
			}
			if (queryMap.get("budgetNumIdList") != null && !"".equals(queryMap.get("budgetNumIdList"))) {
				queryString.append(" and c.budgetNum.numId in (:budgetNumIdList)");
			}
			if (queryMap.get("isAdditional") != null && !"".equals(queryMap.get("isAdditional"))) {
				queryString.append(" and c.isAdditional like :isAdditional");
			}
			if (queryMap.get("addforHolidayCode") != null && !"".equals(queryMap.get("addforHolidayCode"))) {
				String h = (String)queryMap.get("addforHolidayCode");
				double addh = Double.valueOf(h);
				queryMap.put("addforHolidayCode", addh);
				queryString.append(" and c.addforHoliday like :addforHolidayCode");
			}
			if (queryMap.get("checkNo") != null && !"".equals(queryMap.get("checkNo"))) {
				queryString.append(" and c.checkNo like :checkNo");
			}
			if (queryMap.get("isCommit") != null && !"".equals(queryMap.get("isCommit"))) {
				queryString.append(" and c.ratestutas like :isCommit");
			}
		}
		queryString.append(this.changeOrder(page));
		List<ContractRate> list = contractRateDao.search(queryString.toString(),
				queryMap, page);
		pageEntity.setTotalRecord(contractRateDao.getPageEntity().getTotalRecord());
		return list;
	}
	
	/**
	 * 
	 * @param companyId
	 * @param profeid
	 * @param orderdate
	 * @return
	 */
	public List<ContractRate> listPersonOrder(Long companyId,Long profeid,Date orderdate){
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("companyId", companyId);
		map.put("profeid", profeid);
		map.put("orderdate", orderdate);
		map.put("ratestutas", "Y");
		String hql = "from ContractRate t where t.contract.company.companyId=:companyId" +
				" and t.profession.profeid=:profeid and t.effectiveDate<=:orderdate and t.expirationDate>=:orderdate and t.ratestutas=:ratestutas";
		List<ContractRate> list = contractRateDao.search(hql,map,null);
		return list;
	}
	
	public ContractRate findById(Long id){
		return contractRateDao.findById(id);
	}
	
	private String changeOrder(PageEntity entity) {
		String str = " order by c.";
		if (entity != null && entity.getField() != null
				&& !entity.getField().equals("")) {
			if (entity.getField().equals("companySName"))
				str += "company.companySName ";
			else if (entity.getField().equals("contractName"))
				str += "contract.contractType.typeId ";
			else if (entity.getField().equals("contractNo"))
				str += "contract.contractNo ";
			else if (entity.getField().equals("effectiveDate"))
				str += "effectiveDate ";
			else if (entity.getField().equals("expirationDate"))
				str += "expirationDate ";
			else if (entity.getField().equals("profeName"))
				str += "profession.profeid ";
			else if (entity.getField().equals("ratestutas"))
				str += "ratestutas ";
			else if (entity.getField().equals("wharfName"))
				str += "contract.wharf ";
			else if (entity.getField().equals("addforHoliday"))
				str += "addforHoliday ";
			else if (entity.getField().equals("checkNo"))
				str += "checkNo ";
			else if (entity.getField().equals("budgetNumName"))
				str += "budgetNum.numId ";
			else if (entity.getField().equals("rate"))
				str += "rate ";
			else if (entity.getField().equals("currencyName"))
				str += "currency ";
			else if (entity.getField().equals("unit"))
				str += "unit ";
			else if (entity.getField().equals("isAdditional"))
				str += "isAdditional ";
			else if (entity.getField().equals("quan"))
				str += "startquan ";
			else if (entity.getField().equals("remarks"))
				str += "remarks ";
			else 
				str += "createDate desc";
			str += entity.getOrder();
		} else {
			str += "createDate desc";
		}
		return str;
	}

	/**
	 * 查找是否存在指定的预算编号
	 * @param budgetNum
	 * @return true - 存在
	 */
	public boolean check(BudgetNum budgetNum) {
		StringBuilder queryString = new StringBuilder();
		Map<String, Object> queryMap = new HashMap<String, Object>();
		queryString.append("from ContractRate as c where 1=1 and c.budgetNum.numId =:budgetNum order by c.createPerson");
		queryMap.put("budgetNum", budgetNum.getNumId());
		List<ContractRate> list =  contractRateDao.search(queryString.toString(),queryMap,null);
		if (list == null || list.size() <= 0) {
			return false;
		}
		return true;
	}
	
	/**
	 * 
	 * @param companyid 承包商主键
	 * @param profeid 工种主键
	 * @param efDate 服务日期，必须包含在生效日期和截止日期之间
	 * @param number 数量，开始数量必须小于此数量number得记录中最开始数量最大的
	 * @return 合同费率
	 */
	public List<ContractRate>  queryRate(Long companyid,Long profeid,Date efDate,BigDecimal number){
		String hql = "from ContractRate c where c.contract.company.companyId = :companyId " +
				"and c.profession.profeid = :profeid and c.effectiveDate <= :efDate and c.expirationDate >= :efDate " +
				"and (c.startquan <= :number or c.startquan is null) order by c.startquan desc";
		Map<String, Object> queryMap = new HashMap<String, Object>();
		queryMap.put("companyId", companyid);
		queryMap.put("profeid", profeid);
		queryMap.put("efDate", efDate);
		queryMap.put("number", number.doubleValue());
		List<ContractRate> list;
		try {
			list = contractRateDao.search(hql, queryMap, null);
		} catch (Exception e) {
			list = new ArrayList<ContractRate>();
		}
		
		return list;
	}

	/**
	 * 查找重叠记录
	 * @param contractRate 
	 * @param isSave 是否保存
	 * @param equals  时间是否重叠
	 * @param isStartquan 起始/结束时间
	 * @return
	 */
	public ContractRate check(ContractRate contractRate, boolean isSave, boolean equals, boolean isStartquan) {
		StringBuilder queryString = new StringBuilder();
		Map<String, Object> queryMap = new HashMap<String, Object>();
		queryString.append("from ContractRate as c where 1=1 and lower(c.company.companySName) =:companySName and c.profession.profeid =:profeid");
		queryMap.put("companySName", contractRate.getCompany().getCompanySName()==null ? null : contractRate.getCompany().getCompanySName().toLowerCase());
		queryMap.put("profeid", contractRate.getProfession().getProfeid());
		
		if(equals) {
			queryString.append(" and ((c.effectiveDate >=:effectiveDate and c.effectiveDate <=:expirationDate) " +
			"or (c.expirationDate >=:effectiveDate and c.expirationDate <=:expirationDate)) ");
			queryMap.put("effectiveDate", contractRate.getEffectiveDate());
			queryMap.put("expirationDate", contractRate.getExpirationDate());
			
			if(!isSave) {
				queryString.append(" and c.rateId not in (:rateId)");
				queryMap.put("rateId", contractRate.getRateId());
			}
		} else {
			if(isStartquan) {
				queryString.append(" and c.startquan =:startquan ");
				queryMap.put("startquan", contractRate.getStartquan());
			} else {
				queryString.append(" and c.endquan =:endquan ");
				queryMap.put("endquan", contractRate.getEndquan());
			}
			 
			if(!isSave) {
				queryString.append(" and c.rateId not in (:rateId)");
				queryMap.put("rateId", contractRate.getRateId());
			}
		}
		
		List<ContractRate> list =  contractRateDao.search(queryString.toString(),queryMap,null);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}
	
	/**
	 * 查找重叠记录
	 * @param contractRate 
	 * @param isSave 是否保存
	 * @param equals  时间是否重叠
	 * @return
	 */
	public ContractRate check(ContractRate contractRate, boolean isSave, boolean equals) {
		StringBuilder queryString = new StringBuilder();
		Map<String, Object> queryMap = new HashMap<String, Object>();
		queryString.append("from ContractRate as c where 1=1 and c.company.companySName =:companySName and c.profession.profeid =:profeid");
		queryMap.put("companySName", contractRate.getCompany().getCompanySName()==null ? null : contractRate.getCompany().getCompanySName().toLowerCase());
		queryMap.put("profeid", contractRate.getProfession().getProfeid());
		
		if(equals) {
			queryString.append(" and ((c.effectiveDate >=:effectiveDate and c.effectiveDate <=:expirationDate) " +
			"or (c.expirationDate >=:effectiveDate and c.expirationDate <=:expirationDate)) ");
			queryMap.put("effectiveDate", contractRate.getEffectiveDate());
			queryMap.put("expirationDate", contractRate.getExpirationDate());
			
			if(!isSave) {
				queryString.append(" and c.rateId not in (:rateId)");
				queryMap.put("rateId", contractRate.getRateId());
			}
		} else {
			queryString.append(" and ((c.startquan >=:startquan and c.startquan <= :endquan) or " +
					"(c.endquan >=:startquan and c.endquan <= :endquan))");
			queryMap.put("startquan", contractRate.getStartquan());
			queryMap.put("endquan", contractRate.getEndquan());
			
			if(!isSave) {
				queryString.append(" and c.rateId not in (:rateId)");
				queryMap.put("rateId", contractRate.getRateId());
			}
		}
		
		List<ContractRate> list =  contractRateDao.search(queryString.toString(),queryMap,null);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}
}
